<?php

namespace app\system\service;

use app\model\Device;
use app\model\DeviceSync;
use app\traits\ServiceTrait;
use app\traits\UserTrait;
use think\db\Query;
use think\helper\Arr;

class DeviceService
{
    use UserTrait;
    use ServiceTrait;

    /**
     * @return array
     */
    public function types(): array
    {
        $types = [];
        foreach (Device::types() as $value => $label) {
            $types[] = [
                'value' => $value,
                'label' => $label
            ];
        }
        return $types;
    }

    /**
     * @param array $params
     * @param $adminId
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function save(array $params, $adminId = 0): array
    {
        //sn唯一性
        if (Device::where(['serial_no' => $params['serial_no']])->find()) {
            return [false, '设备编号需要唯一，不能重复'];
        }
        $params['created_by'] = $this->getUid($adminId);
        return [true, Device::create($params)];
    }

    /**
     * 同步过来的设备
     * @return DeviceSync[]|array|\think\Collection
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function syncDevice()
    {
        return DeviceSync::select();
    }


    public function getList(?array $params, $select = ['*'], $sample = false)
    {
        $query = Device::order(['id' => 'desc']);
        if ($type = Arr::get($params, 'type')) {
            $query->where(['type' => $type]);
        }
        if ($name = Arr::get($params, 'name')) {
            $query->where(['name' => $name]);
        }
        if ($ip = Arr::get($params, 'ip')) {
            $query->where(['id' => Device::where(['ip' => $ip, 'type' => Device::DEVICE_TYPE_YTJ])->value('id')]);
        }
        if ($serialNo = Arr::get($params, 'serial_no')) {
            $query->where(['serial_no' => $serialNo]);
        }
//        if ($status = Arr::get($params, 'status')) {
//            $query->where(['status' => $status]);
//        }
//        if ($onlieStatus = Arr::get($params, 'online_status')) {
//            $query->where(['online_status' => $onlieStatus]);
//        }
        $pagination = $query
            ->field($select)
            ->with([
                'sync' => function (Query $query) {
                    $query->field('online_status');
                },
                'stock'
            ])
            ->filter(function ($model) {
                $model->online_status = $model->sync?->online_status ?? 0;
                $model->stock_id = $model->stock?->stock_id ?? 0;;
            })->hidden(['sync', 'stock'])
            ->paginate([
                'list_rows' => Arr::get($params, $this->listRowsName('system'), 15),
                'var_page' => 'page',
            ]);
        return $sample ? $pagination->items() : pagination($pagination);
    }


    public function update($id, array $data): array
    {
        if (!$model = Device::where(['id' => $id])->find()) {
            return [false, '设备信息不存在'];
        }

        if ($serialNo = Arr::get($data, 'serial_no')) {
            $exist = Device::where(['serial_no' => $serialNo])->find();
            if ($exist && $exist['id'] != $id) {
                return [false, '设备编号已经存在'];
            }
        }

        if (Arr::get($data, 'source') == 'api') {
            if (!$pushTime = Arr::get($data, 'push_time')) {
                return [false, '缺少必要参数push_time'];
            }
            if ($pushTime < $model->updated_at) {
                return [false, '当前修改时间已经失效,请重试'];
            }
        }
        return [true, $model->save($data)];
    }

    public function batchUpdateStatus($data)
    {
        if (!$statusSetting = Arr::get($data, 'status_setting')) {
            return [false, '缺少必要参数status_setting'];
        }
        $allIds = $onIds = $offIds = [];
        foreach ($statusSetting as $item) {
            if ($item['status'] == 1) {
                $onIds[] = $item['id'];
            } else {
                $offIds[] = $item['id'];
            }
            $allIds[] = $item['id'];
        }

        if (Arr::get($data, 'source') == 'api') {
            $pushTime = Arr::get($data, 'push_time');
            //查找要修改的id最早的修改时间
            $updatedAt = Device::where(['id' => $allIds])->order('updated_at', 'asc')->value('updated_at');
            if ($updatedAt > $pushTime) {
                return [false, '当前修改时间已经失效,请重试'];
            }
        }

        try {
            Device::update(['status' => 1], ['id' => $onIds]);
            Device::update(['status' => 2], ['id' => $offIds]);
        } catch (\Exception $exception) {
            return [false, $exception->getMessage()];
        }
        return [true, []];
    }

    /**
     * 删除
     * @param $id
     * @param $adminId
     * @return array
     */
    public function del($id, $adminId = 0)
    {
        $model = Device::update([
            'deleted_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
            'updated_by' => $this->getUid($adminId),
        ], ['id' => $id]);
        return [true, $model];
    }

    /**
     * @param $id
     * @return array
     */
    public function read($id): array
    {

        return Device::where(['id' => $id])->findOrEmpty()->toArray();
    }
}